#include "rxe.h"

int rxe_alloc_mw(struct ib_mw *ibmw, struct ib_udata *udata)
{
    struct rxe_mw *mw = to_rmw(ibmw);
    struct rxe_pd *pd = to_rpd(ibmw->pd);
    struct rxe_dev *rxe = to_rdev(ibmw->device);
    int ret;

    rxe_add_ref(pd);

    ret = rxe_add_to_pool(&rxe->mw_pool, mw);
    if (ret) {
        rxe_drop_ref(pd);
        return ret;
    }

    rxe_add_index(mw);
    mw->rkey = ibmw->rkey = (mw->pelem.index << 8) | rxe_get_next_key(-1);
    mw->state = (mw->ibmw.type == IB_MW_TYPE_2) ? RXE_MW_STATE_FREE : RXE_MW_STATE_VALID;
    spin_lock_init(&mw->lock);

    return 0;
}


static void rxe_do_dealloc_mw(struct rxe_mw *mw)
{


}

int rxe_dealloc_mw(struct ib_mw *ibmw)
{
    struct rxe_mw *mw = to_rmw(ibmw);
    struct rxe_pd *pd = to_rpd(ibmw->pd);
    unsigned long flags;




    return 0;
}

static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
        struct rxe_mw *mw, struct rxe_mr *mr)
{

    return 0;
}

static void rxe_do_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe,
        struct rxe_mw *mw, struct rxe_mr *mr)
{
    u32 key = wqe->wr.wr.mw.rkey & 0xff;


}

int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe)
{
    int ret;
    struct rxe_mw *mw;
    struct rxe_mr *mr;
    struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
    u32 mw_rkey = wqe->wr.wr.mw.mw_rkey;
    u32 mr_lkey = wqe->wr.wr.mw.mr_lkey;
    unsigned long flags;


    return ret;
}

static int rxe_check_invalidate_mw(struct rxe_qp *qp, struct rxe_mw *mw)
{


    return 0;
}

static void rxe_do_invalidate_mw(struct rxe_mw *mw)
{
    struct rxe_qp *qp;
    struct rxe_mr *mr;



}

int rxe_invalidate_mw(struct rxe_qp *qp, u32 rkey)
{
    struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
    unsigned long flags;
    struct rxe_mw *mw;
    int ret;



    return ret;
}

struct rxe_mw *rxe_lookup_mw(struct rxe_qp *qp, int access, u32 rkey)
{
    struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
    struct rxe_pd *pd = to_rpd(qp->ibqp.pd);
    struct rxe_mw *mw;
    int index = rkey >> 8;

    mw = rxe_pool_get_index(&rxe->mw_pool, index);
    if (!mw)
        return NULL;

    //...

    return mw;
}

void rxe_mw_cleanup(struct rxe_pool_entry *elem)
{
    struct rxe_mw *mw = container_of(elem, typeof(*mw), pelem);

    rxe_drop_index(mw);
}

